package cn.gan.loveofsoul.controller;

import cn.gan.loveofsoul.commons.result.ErrorMessage;
import cn.gan.loveofsoul.commons.result.Result;
import cn.gan.loveofsoul.commons.result.StatusCode;
import cn.gan.loveofsoul.commons.utils.FileUtil;
import cn.gan.loveofsoul.commons.utils.UUIDUtil;
import cn.gan.loveofsoul.exception.BusinessException;
import cn.gan.loveofsoul.service.IFileUploadService;
import cn.hutool.core.collection.CollectionUtil;
import com.mongodb.BasicDBObject;
import com.mongodb.DBObject;
import com.mongodb.client.gridfs.model.GridFSFile;
import org.bson.types.ObjectId;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.gridfs.GridFsResource;
import org.springframework.data.mongodb.gridfs.GridFsTemplate;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;


import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletResponse;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Objects;

/**
 * @Description:
 * @Author: ganwh
 * @Since: 2023/10/24 11:39
 */
@RequestMapping("/file")
@Controller
public class FileUploadController {

    private static final Logger logger = LoggerFactory.getLogger(FileUploadController.class);

    @Autowired
    private GridFsTemplate gridFsTemplate;
    @Autowired
    private IFileUploadService fileUploadService;

    /**
     * 功能描述: 上传文件接口
     *
     * @param clientFile
     * @return cn.gan.loveofsoul.commons.result.Result
     * @author ganwh 2023/10/24 18:03
     */
    @PostMapping("/upload")
    @ResponseBody
    public Result uploadFile(@RequestParam("clientFile") MultipartFile clientFile) {
        Map<String, String> uploadMap = fileUploadService.uploadFile(clientFile);
        return new Result(StatusCode.SUCCESS, "上传成功", uploadMap.get("fileId"));
    }

    /**
     * 功能描述: 批量上传文件
     *
     * @param clientFiles
     * @return cn.gan.loveofsoul.commons.result.Result
     * @author ganwh 2023/11/7 18:11
     */
    @PostMapping("/uploadFiles")
    @ResponseBody
    public Result uploadFiles(@RequestParam("clientFile") MultipartFile[] clientFiles) {
        Result result;
        List<Map<String, String>> uploadResult = new ArrayList<>();
        try {
            for (MultipartFile clientFile : clientFiles) {
                Map<String, String> uploadMap = fileUploadService.uploadFile(clientFile);
                uploadResult.add(uploadMap);
            }
            result = new Result(StatusCode.SUCCESS, "上传成功", uploadResult);
        } catch (Exception ex) {
            logger.error("上传文件失败 -> ", ex);
            if (CollectionUtil.isNotEmpty(uploadResult)) {
                uploadResult.forEach(file -> {
                    Query query = Query.query(Criteria.where("metadata.fileId").is(file.get("fileId")));
                    gridFsTemplate.delete(query);
                });
            }
            result = new Result(StatusCode.ERROR, "上传失败");
        }
        return result;
    }

    /**
     * 功能描述: 预览图片
     *
     * @param fileId
     * @param response
     * @return void
     * @author ganwh 2023/11/7 18:11
     */
    @GetMapping("/getImage")
    @ResponseBody
    public void getImage(@RequestParam("fileId") String fileId, HttpServletResponse response) {
        Query query = Query.query(Criteria.where("metadata.fileId").is(fileId));
        GridFSFile file = gridFsTemplate.findOne(query);
        if (Objects.isNull(file)) {
            logger.error("文件不存在，文件ID -> {}", fileId);
            throw new BusinessException(StatusCode.NOT_FOUND, ErrorMessage.FILE_NOT_FOUND);
        }
        GridFsResource gridFsResource = gridFsTemplate.getResource(file);
        try (OutputStream outputStream = response.getOutputStream();
             // 将图片转化为图片流
             ByteArrayOutputStream baos = new ByteArrayOutputStream()) {

            // 读取图片文件
            BufferedImage bufferedImage = ImageIO.read(gridFsResource.getInputStream());

            // 图片写入输出流
            ImageIO.write(bufferedImage, "jpeg", baos);

            // 将图片流写入响应输出流
            // 禁止图像缓存。
            response.setHeader("Pragma", "no-cache");
            response.setHeader("Cache-Control", "no-cache");
            response.setDateHeader("Expires", 0);
            response.setContentType("image/jpeg");
            outputStream.write(baos.toByteArray());
        } catch (Exception ex) {
            logger.error("预览失败 -> ", ex);
            throw new BusinessException(StatusCode.ERROR, ErrorMessage.SYSTEM_ERROR);
        }
    }
}
